(function ($) {
  // register namespace
  $.extend(true, window, {
    "Slick": {
      "GanttRangeDecorator": GanttRangeDecorator
    }
  });

  /***
   * Displays an overlay on top of a given cell range.
   *
   * TODO:
   * Currently, it blocks mouse events to DOM nodes behind it.
   * Use FF and WebKit-specific "pointer-events" CSS style, or some kind of event forwarding.
   * Could also construct the borders separately using 4 individual DIVs.
   *
   * @param {Grid} grid
   * @param {Object} options
   */
  function GanttRangeDecorator(grid, options) {
    var _pL;
    var _pR;
    var _bar;
    var _line;
    var _rElem;
    var _this;
    if (!grid.bar) {
      grid.bar = [];
    }
    _this = this;

    grid.bar.push(_this);


    var _borderWidth;
    var _defaults = {
      selectionCssClass: 'slick-range-decorator',
      ganttLinkControlCssClass: 'gantt_link_control',
      selectionCss: {
        "zIndex": "9999",
        "border": "2px dashed red"
      },
      lSelectionCss: {
        "zIndex": "9999",
        "border-color": "red",
        "border-style": "dashed",
        "border-top-width": "2px",
        "border-right-width": "0px",
        "border-bottom-width": "2px",
        "border-left-width": "2px"
      },
      rSelectionCss: {
        "zIndex": "9999",
        "border-color": "red",
        "border-style": "dashed",
        "border-top-width": "2px",
        "border-right-width": "2px",
        "border-bottom-width": "2px",
        "border-left-width": "0px"
      }
      , gantt_link_control_left: {
        "left": "-6.5px",
      },
      gantt_link_control_right: {
        "right": "-13.5px",
      },
    };

    options = $.extend(true, {}, _defaults, options);

    function bindPoint(point, direct) {
      var startPoint;
      var draggen = false;
      point.bind("draginit", function () {
        console.log("start")
      }).bind("dragstart", { distance: 3 }, function (e) {
        draggen = true;

        startPoint = { pageX: e.pageX - e.offsetX, pageY: e.pageY + e.offsetY, offsetX: point.width() / 2, offsetY: 1 + point.height() / 2 }
        lastDgree = 0;
        if (!_line) {
          _line = $('<div class="gantt_link_group"></div>').appendTo(grid.getGanttCanvasLinkArea())
        }
        var line = $('<div class="gantt_link_direction"   width: 310px; top: 6px; left:  6.5px;"></div>');
        line.appendTo(point);
        point.css("background-color", "yellow");

      }).bind("drag", function (e) {
        var distance = Math.sqrt(Math.pow(Math.abs(startPoint.pageX - e.pageX), 2) + Math.pow(Math.abs(e.pageY - startPoint.pageY), 2));
        var dgree = getAngle(startPoint.pageX, startPoint.pageY, e.pageX, e.pageY);
        point.children().css("width", distance + "px")
        point.children().css("transform", 'rotate(' + (dgree - 90) + 'deg)')
      }).bind("dragend", function (e) {
        point.hide();
        point.empty();

        var findT = false;
        for (var i = 0; i < grid.bar.length; i++) {
          var tBar = grid.bar[i];
          if (tBar != _this) {
            findT = true;
          }
        }
        if (!findT) {
          return;
        }


        _bar.children("." + options.ganttLinkControlCssClass).css('display', 'none');
        draggen = false;

        var topLine = $("<div ></div>").addClass("gantt_link_line_horizon")
          .css("position", "absolute")
          .css("top", startPoint.pageX <= e.pageX ? startPoint.offsetY : e.pageY - startPoint.pageY)
          .css("left", -24)
          .appendTo(_bar);
        topLine.css("width", "20px");

        var down = $("<div ></div>").addClass("gantt_link_line_down")
          .css("position", "absolute")
          .css("top", startPoint.offsetY)
          .css("left", startPoint.pageX <= e.pageX ? -24 : - (Math.abs(e.pageX - startPoint.pageX) + 20))
          .appendTo(_bar);
        down.css("height", e.pageY - startPoint.pageY);

        var bottomLine = $("<div ></div>").addClass("gantt_link_line_horizon")
          .css("position", "absolute")
          .css("top", startPoint.pageX <= e.pageX ? e.pageY - startPoint.pageY + point.height() / 2 : startPoint.offsetY)
          .css("left", startPoint.pageX <= e.pageX ? -24 : - (Math.abs(e.pageX - startPoint.pageX) + 20))
          .appendTo(_bar);
        bottomLine.css("width", Math.abs(e.pageX - startPoint.pageX) + 20);

        var arrow = $("<div ></div>").addClass("gantt_link_line_arrow").addClass("gantt_link_line_arrow_left")
          .css("position", "absolute")
          .css("top", startPoint.pageX <= e.pageX ? e.pageY - startPoint.pageY + point.height() / 2 - 4.5 : startPoint.offsetY)
          .css("left", e.pageX - startPoint.pageX - 10)
          .appendTo(_bar);

      })
    }

    var i = 0;
    function show(range, cfg) {
      var canvas = cfg.canvas;
      var start = cfg.start;
      var end = cfg.end;
      var from = grid.getCellNodeBox(range.fromRow, range.fromCell);
      var to = grid.getCellNodeBox(range.fromRow, range.toCell);

      // range left to right 
      var directLR = start <= end;
      // frozenColumn temp var 
      var frozenColumn = grid.getOptions().frozenColumn;

      var lR = false;
      // lR true condition
      if (directLR) {
        lR = start <= frozenColumn && end > frozenColumn;
      } else {
        lR = start > frozenColumn && end <= frozenColumn;
      }

      if (!_bar) {
        _bar = $("<div></div>", { css: options.selectionCss })
          .addClass(options.selectionCssClass)
          .css("position", "absolute")
          .appendTo(grid.getGanttCanvasBarArea());


        _borderWidth = 0
        // gantt stone
        // _borderWidth = _bar.css("border-left-width");

        // 20220305 增加连线


        _pL = $("<div ></div>", { css: options.gantt_link_control_left }).addClass(options.ganttLinkControlCssClass)
          .css("position", "absolute")
          .appendTo(_bar);

        // 20220305 增加连线
        _pR = $("<div ></div>", { css: options.gantt_link_control_right }).addClass(options.ganttLinkControlCssClass)
          .css("position", "absolute")
          .appendTo(_bar);
        bindPoint(_pL);
        bindPoint(_pR);

        _bar.mousedown(function () {
          // gantt stone
          // hide();
        });

        _bar.mousemove(function () {
          _bar.css("background-color", "lightGray");
          _bar.children("." + options.ganttLinkControlCssClass).css('display', 'block');
        })

        _bar.mouseout(function () {
          _bar.css("background-color", "red");
          if (!draggen) {
            _bar.children("." + options.ganttLinkControlCssClass).css('display', 'none');
          }

        })
      }

      var _barStart;
      _bar.bind("dragstart", { distance: 3 }, function (e) {

        draggen = true;
        _barStart = e;
      }).bind("drag", function (e) {
        _bar.css("background-color", "yellow");
        range.fromCell = range.fromCell + (_barStart.pageX - e.pageX) / 40;
        range.toCell = range.toCell + 1;
        show(range, cfg)
      }).bind("dragend", function (e) {

      });

      // lr ,create new element .
      if (lR && !_rElem) {
        _rElem = $("<div></div>", { css: options.selectionCss })
          .addClass(options.selectionCssClass)
          .css("position", "absolute")
          .appendTo(canvas);
        _rElem.mousedown(function () {
          // gantt stone
          //  hide();
        });
      }

      // ! lr ,remove _rElem
      if (!lR && _rElem) {
        _rElem.remove();
        _rElem = null;
      }

      var temp = lR && directLR ? _rElem : _bar;
      var lWidth = lR ? directLR ? canvas.width() : to.right - 2 : (to.right - from.left - 2);
      var lLeft = lR && !directLR ? 0 : (from.left - 1);
      //console.log("DIRECT_LR:" + directLR + " FROM_L:" + from.left + " TO_L:" + to.left + " FROM_R:" + from.right + " TO_R" + to.right + " START:" + start + " END:" + end + " LWIDTH:" + lWidth)
      if (_bar) {
        _bar.css("border-right-width", lR ? directLR ? "0px" : _borderWidth : _borderWidth);
        _bar.css("border-left-width", lR ? directLR ? _borderWidth : "0px" : _borderWidth);
        _bar.css({
          top: from.top - 1,
          left: lLeft,
          height: to.bottom - from.top - 8,
          width: lWidth - 6,
          margin: '6px',
          'background-color': 'red',
          "border-top-width": "0px",
          "border-bottom-width": "0px",
        });
      }

      if (_rElem) {
        var rLeft = directLR ? 0 : from.left;
        var rWidth = !directLR ? canvas.width() : (to.right - 2);
        //console.log("RWIDTH:" + rWidth + " RLEFT:" + rLeft);
        _rElem.css("border-left-width", lR ? directLR ? "0px" : _borderWidth : _borderWidth);
        _rElem.css("border-right-width", lR ? directLR ? _borderWidth : "0px" : _borderWidth);
        _rElem.css({
          top: from.top - 1,
          left: rLeft,
          height: to.bottom - from.top - 2,
          width: rWidth
        });
      }
      return temp;
    }

    function getAngle(px, py, mx, my) {//获得人物中心和鼠标坐标连线，与y轴正半轴之间的夹角
      var x = Math.abs(px - mx);
      var y = Math.abs(py - my);
      var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
      var cos = y / z;
      var radina = Math.acos(cos);//用反三角函数求弧度
      var angle = Math.floor(180 / (Math.PI / radina));//将弧度转换成角度

      if (mx > px && my > py) {//鼠标在第四象限
        angle = 180 - angle;
      }

      if (mx == px && my > py) {//鼠标在y轴负方向上
        angle = 180;
      }

      if (mx > px && my == py) {//鼠标在x轴正方向上
        angle = 90;
      }

      if (mx < px && my > py) {//鼠标在第三象限
        angle = 180 + angle;
      }

      if (mx < px && my == py) {//鼠标在x轴负方向
        angle = 270;
      }

      if (mx < px && my < py) {//鼠标在第二象限
        angle = 360 - angle;
      }

      return angle;
    }



    function hide() {
      if (_bar) {
        _bar.remove();
        _bar = null;
      }

      if (_rElem) {
        _rElem.remove();
        _rElem = null;
      }
    }
    var range;
    var cfg;
    function dragEnd(range, cfg) {
      range = range;
      cfg = cfg;
    }

    $.extend(this, {
      "show": show,
      "hide": hide,
      "dragEnd": dragEnd
    });
  }
})(jQuery);
